<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2021/8/14
 * Time: 15:58
 */

namespace App\Service;


use App\Models\FloorRoom;
use App\Models\Order;
use App\Models\Config;
use EasyWeChat\Factory;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Yansongda\Pay\Pay;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;

class OrderService
{
    /**
     * 获取订单列表
     * @param array $params
     * @param string $orderBy
     * @param string $sort
     * @param int $page
     * @param int $limit
     * @return \Illuminate\Http\JsonResponse
     */
    public static function getList($params = [],$orderBy = 'id',$sort = 'DESC',$page=1,$limit = 10)
    {
        $floorWhere = $where = $buildingWhere = [];
//        $orderModel = new Order();
        if(isset($params['order_no']) && !empty(trim($params['order_no']))){
            $where[] = ['order_no','=',trim($params['order_no'])];
        }
        if(isset($params['start_time']) && !empty(trim($params['start_time']))){
            $end_time = strtotime(trim($params['start_time'])) + 60*60*24;
            $floorWhere[] = $buildingWhere[] = $where[] = ['created_at','>=',date("Y-m-d H:i:s",strtotime(trim($params['start_time'])))];
            $floorWhere[] = $buildingWhere[] = $where[] = ['created_at','<',date('Y-m-d H:i:s',$end_time)];
        }
        // else{
        //     $where[] = ['pay_at','>=',date('Y-m-d',strtotime('-1 day'))." 0:0:0"];
        //     $where[] = ['pay_at','<',date('Y-m-d',strtotime('-1 day'))." 24:0:0"];
        // }
        if(isset($params['end_time']) && !empty(trim($params['end_time']))){
            $where[] = ['created_at','<',trim($params['end_time'])];
        }
        if(isset($params['status']) && !empty(intval($params['status']))){
            $floorWhere[] = $buildingWhere[] = $where[] = ['status','=',intval($params['status'])];
        }

        if(isset($params['building_no']) && !empty(intval($params['building_no']))){
            $floorWhere[] = $buildingWhere[] = $where[] = ['building_no','=',intval($params['building_no'])];

        }
        if(isset($params['floor_no']) && !empty(intval($params['floor_no']))){
            $floorWhere[] = $where[] = ['floor_no','=',intval($params['floor_no'])];
        }
        if(isset($params['water_type']) && !empty(intval($params['water_type']))){
            $where[] = ['water_type','=',intval($params['water_type'])];
        }
        $start=($page-1)*$limit;
        $list = Order::with(['userItem'=>function($query){
            return $query->select(['id','username','name']);
        },'memberItem'=>function($query){
            return $query->select(['id','nickname','avatar']);
        }])->where($where)->whereIn('status',[2,3,4])->orderBy($orderBy,$sort)->skip($start)->take($limit)->get()->toArray();
        $config = Config::where('id', 1)->first(['id', 'site_name', 'logo_src', 'notice', 'nf_price', 'jt_price', 'jt_name', 'nf_name', 'created_at', 'updated_at']);

        foreach($list as $k => $v){
            $list[$k]['pay_at'] = $v['pay_at'] ? date('H:i',strtotime($v['pay_at'])) : '';
            $list[$k]['created_at'] = $v['created_at'] ? date('H:i',strtotime($v['created_at'])) : '';
            $list[$k]['refund_at'] = $v['refund_at'] ? date('H:i',strtotime($v['refund_at'])) : '';
            $list[$k]['delivery_at'] = $v['delivery_at'] ? date('H:i',strtotime($v['delivery_at'])) : '';
            $list[$k]['water_type_name'] = $v['water_type'] == 1 ? $config->nf_name : $config->jt_name;
        }
        $count = Order::where($where)->whereIn('status',[2,3,4])->count();
        $pageCount = ceil($count/$limit);
        $buildingNfCount= Order::where($buildingWhere)->whereIn('status',[2,3,4])->where('water_type',1)->sum('num');
        $buildingJtCount = Order::where($buildingWhere)->whereIn('status',[2,3,4])->where('water_type',2)->sum('num');
        $floorNfCount = Order::where($floorWhere)->whereIn('status',[2,3,4])->where('water_type',1)->sum('num');
        $floorJtCount = Order::where($floorWhere)->whereIn('status',[2,3,4])->where('water_type',2)->sum('num');
        $data = [
            'list'          => $list,
            'pageCount'     => $pageCount,
            'buildingNfCount'   => $buildingNfCount ? $buildingNfCount : 0,
            'buildingJtCount'   => $buildingJtCount ? $buildingJtCount : 0,
            'floorNfCount'      => $floorNfCount ? $floorNfCount : 0,
            'floorJtCount'      => $floorJtCount ? $floorJtCount : 0,
            'nfName'      => $config->nf_name ?: '',
            'jtName'      => $config->jt_name ?: '',
        ];
        return Response()->json(['code'=>200,'msg'=>'获取成功','data'=>$data]);
    }

    /**
     * 通过ID获取订单
     * @param int $orderId
     * @return array
     */
    public static function getOrderById($orderId = 0)
    {
        $info = Order::with([['userItem'=>function($query){
            return $query->select(['id','username','name']);
        },'memberItem'=>function($query){
            return $query->select(['id','nickname','avatar']);
        }]])->where('id', $orderId)->first(['id', 'mid','order_no','room_id','building_no','floor_no','room_no','water_type','num','price','prepare_id','status','user_id','pay_at','delivery_at','created_at', 'updated_at']);
        $info = $info ? $info->toArray() : [];
        return Response()->json(['code' => 200, 'msg' => '获取成功', 'data' => $info]);

    }

    /**
     * 修改
     * @param array $params
     * @return \Illuminate\Http\JsonResponse
     */
    public static function edit($params = [])
    {
        try{
            $info = Order::where('id',intval($params['id']))->first();
            if(!$info){
                throw new \Exception('订单不存在');
            }
            if($info->status != 3 && intval($params['status']) == 3){
                $info->delivery_at = date('Y-m-d H:i:s');
                $token = Request()->header('token');
                $cacheMember = Cache::get($token);
                $info->user_id = $cacheMember['id'];
            }
            $info->status = intval($params['status']);
            $info->water_type = intval($params['water_type']);
            $info->num = intval($params['num']);


            $save = $info->save();
            if(!$save){
                throw new \Exception('修改失败');
            }
        }catch (\Exception $e){
            return Response()->json(['code'=>201,'msg'=>$e->getMessage()]);
        }
        return Response()->json(['code'=>200,'msg'=>'修改成功']);
    }

    /**
     * 配送
     * @param array $params
     * @return \Illuminate\Http\JsonResponse
     */
    public static function delivery($params = [])
    {
        try{
            DB::connection()->enableQueryLog();
            $token = Request()->header('token');
            $cacheMember = Cache::get($token);
            $time = date('Y-m-d H:i:s');

            if(isset($params['building_no']) || isset($params['floor_no'])){//整层配送
                $where = [];
                if(!intval($params['building_no'])){
                    throw new \Exception('请选择公寓栋数');
                }
                if(!intval($params['floor_no'])){
                    throw new \Exception('请选择公寓楼层数');
                }

                if(isset($params['start_time']) && !empty(trim($params['start_time']))){
                    $end_time = strtotime(trim($params['start_time'])) + 60*60*24;
                    $where[] = ['created_at','>=',date("Y-m-d",strtotime(trim($params['start_time'])))];
                    $where[] = ['created_at','<',date('Y-m-d H:i:s',$end_time)];
                }else{
                    throw new \Exception('请选择配送日期');
                    // $where[] = ['pay_at','>=',date('Y-m-d',strtotime('-1 day'))." 0:0:0"];
                    // $where[] = ['pay_at','<',date('Y-m-d',strtotime('-1 day'))." 24:0:0"];
                }

                $idArr = Order::where($where)->where('building_no',intval($params['building_no']))->where('floor_no',intval($params['floor_no']))->where('status',2)->pluck('id')->toArray();
                Log::channel('update_log')->info(json_encode($idArr,JSON_UNESCAPED_UNICODE));
                if(!$idArr){
                    throw new \Exception('该楼层不存在需配送的订单');
                }
                $update = Order::query()->whereIn('id',$idArr)->update(['status'=>3,'delivery_at'=>$time,'user_id'=>$cacheMember['id'],'is_send_delivery'=>1]);
                if(!$update){
                    throw new \Exception('配送失败');
                }
            }elseif(isset($params['id'])){   //单个配送
                $info = Order::query()->where('id',intval($params['id']))->first();
                if(!$info){
                    throw new \Exception('该配送的订单不存在');
                }
                if($info->status != 2){
                    throw new \Exception('该配送的订单不支持配送');
                }
                $update = Order::query()->where('id',intval($params['id']))->update(['status'=>3,'delivery_at'=>$time,'user_id'=>$cacheMember['id'],'is_send_delivery'=>1]);
                if(!$update){
                    throw new \Exception('配送失败');
                }
                Log::channel('update_log')->info(json_encode(DB::getQueryLog(),JSON_UNESCAPED_UNICODE));
            }else{
                throw new \Exception('参数缺失，配送失败');
            }


        }catch (\Exception $e){

            Log::channel('update_log')->info($e->getMessage());
            return Response()->json(['code'=>201,'msg'=>$e->getMessage()]);
        }
        return Response()->json(['code'=>200,'msg'=>'配送成功']);

    }

    /**
     * 删除
     * @param $id
     * @return \Illuminate\Http\JsonResponse
     */
    public static function destroy($id)
    {
        $idArr = is_array($id) ? $id : [$id];
        if(!$idArr){
            return Response()->json(['code'=>201,'msg'=>'请选择要删除的订单']);
        }
        $del = Order::destroy($idArr);
        if($del){
            return Response()->json(['code'=>200,'msg'=>'删除成功']);
        }
        return Response()->json(['code'=>201,'msg'=>'删除失败']);
    }

    /**
     * 获取配送统计信息
     * @return \Illuminate\Http\JsonResponse
     */
    public static function deliveryData($params = [])
    {
        $yesterdayStart = date('Y-m-d',strtotime('-1 day'))." 0:0:0";
        $yesterdayEnd = date('Y-m-d',strtotime('-1 day'))." 24:0:0";
        $todayStart = date('Y-m-d')." 0:0:0";
        if(isset($params['start_time']) && !empty($params['start_time'])){
            $end_time = strtotime(trim($params['start_time'])) + 60*60*24;
            $startDay = date('Y-m-d',strtotime(trim($params['start_time'])));
            $endDay = date('Y-m-d H:i:s',$end_time);
        }else{
            $startDay = date('Y-m-d');
            $endDay = date('Y-m-d',strtotime('+ 1 day'));
        }

        $nfCount = Order::whereBetween('created_at',[$startDay,$endDay])->whereIn('status',[2,3])->where('water_type',1)->sum('num');
        $jtCount = Order::whereBetween('created_at',[$startDay,$endDay])->whereIn('status',[2,3])->where('water_type',2)->sum('num');
        $config = Config::where('id', 1)->first(['id', 'site_name', 'logo_src', 'notice', 'nf_price', 'jt_price', 'jt_name', 'nf_name', 'created_at', 'updated_at']);

        $data = [
            'nfCount'      => $nfCount ? $nfCount : 0,
            'jtCount'      => $jtCount ? $jtCount : 0,
            'nf_name'      => $config->nf_name,
            'jt_name'      => $config->jt_name,
        ];

        return Response()->json(['code'=>200,'msg'=>'获取成功','data'=>$data]);

    }

    /**
     * 房间统计数据
     * @param array $params
     * @return \Illuminate\Http\JsonResponse
     */
    public static function getStatistics($params = [])
    {
        $where = [];
        $token = Request()->header('token');
        $cacheMember = Cache::get($token);
        if(isset($params['start_time']) && !empty(trim($params['start_time']))){
            $where[] = ['created_at','>=',$params['start_time']];
        }
        if(isset($params['end_time']) && !empty(trim($params['end_time']))){
            $end_time = strtotime(trim($params['end_time'])) + 60*60*24;
            $where[] = ['created_at','<=',date('Y-m-d H:i:s',$end_time)];
        }
        if(isset($params['building_no']) && !empty(intval($params['building_no']))){
            $where[] = ['building_no','=',intval($params['building_no'])];
        }
        if(isset($params['floor_no']) && !empty(intval($params['floor_no']))){
            $where[] = ['floor_no','=',$params['floor_no']];
        }
        if(isset($params['room_no']) && !empty(trim($params['room_no']))){
            $where[] = ['room_no','=',$params['room_no']];
        }
        if(isset($params['user_id']) && !empty(intval($params['user_id']))){
            $where[] = ['user_id','=',intval($params['user_id'])];
            // if(intval($params['user_id']) != $cacheMember['id']  && $cacheMember['id'] != 1){
            //     return Response()->json(['code'=>201,'msg'=>'您暂不能看其他配送员信息']);
            // }
        }else{
            // $where[] = ['user_id','=',$cacheMember['id']];
        }
        $nfCount = Order::where($where)->whereIn('status',[2,3])->where('water_type',1)->sum('num');
        $jtCount = Order::where($where)->whereIn('status',[2,3])->where('water_type',2)->sum('num');
        $config = Config::where('id', 1)->first(['id', 'site_name', 'logo_src', 'notice', 'nf_price', 'jt_price', 'jt_name', 'nf_name', 'created_at', 'updated_at']);

        $data = [
            'nfCount'      => $nfCount ? $nfCount : 0,
            'jtCount'      => $jtCount ? $jtCount : 0,
            'nf_name'      => $config->nf_name,
            'jt_name'      => $config->jt_name,
        ];
        return Response()->json(['code'=>200,'msg'=>'获取成功','data'=>$data]);
    }

    /**
     * 员工统计数据
     * @param array $params
     * @return \Illuminate\Http\JsonResponse
     */
    public static function getUserStatistics($params = [])
    {
        $where = $memberWhere = $bulidingWhere =   [];
        $token = Request()->header('token');
        $cacheMember = Cache::get($token);
        if(isset($params['start_time']) && !empty(trim($params['start_time']))){
            $bulidingWhere[] = $memberWhere[] = $where[] = ['created_at','>=',$params['start_time']];
        }
        if(isset($params['end_time']) && !empty(trim($params['end_time']))){
            $end_time = strtotime(trim($params['end_time'])) + 60*60*24;
            $bulidingWhere[] = $memberWhere[] = $where[] = ['created_at','<=',date('Y-m-d H:i:s',$end_time)];
        }
        if(isset($params['building_no']) && !empty(intval($params['building_no']))){
            $bulidingWhere[] = $where[] = ['building_no','=',intval($params['building_no'])];
        }
        if(isset($params['floor_no']) && !empty(intval($params['floor_no']))){
            $where[] = ['floor_no','=',$params['floor_no']];
        }

        if(isset($params['user_id']) && !empty(intval($params['user_id']))){
            $bulidingWhere[] = $memberWhere[] = $where[] = ['user_id','=',intval($params['user_id'])];
        }else{
            // $where[] = ['user_id','=',$cacheMember['id']];
        }
        $buildingNfCount = Order::where($bulidingWhere)->whereIn('status',[2,3])->where('water_type',1)->sum('num');
        $buildingJtCount = Order::where($bulidingWhere)->whereIn('status',[2,3])->where('water_type',2)->sum('num');

        $floorNfCount = Order::where($where)->whereIn('status',[2,3])->where('water_type',1)->sum('num');
        $floorJtCount = Order::where($where)->whereIn('status',[2,3])->where('water_type',2)->sum('num');

        $memberNfCount = Order::where($memberWhere)->whereIn('status',[2,3])->where('water_type',1)->sum('num');
        $memberJtCount = Order::where($memberWhere)->whereIn('status',[2,3])->where('water_type',2)->sum('num');
        $config = Config::where('id', 1)->first(['id', 'site_name', 'logo_src', 'notice', 'nf_price', 'jt_price', 'jt_name', 'nf_name', 'created_at', 'updated_at']);

        $data = [
            'buildingNfCount'       => $buildingNfCount ? $buildingNfCount : 0,
            'buildingJtCount'       => $buildingJtCount ? $buildingJtCount : 0,
            'floorNfCount'          => $floorNfCount ? $floorNfCount : 0,
            'floorJtCount'          => $floorJtCount ? $floorJtCount : 0,
            'memberNfCount'         => $memberNfCount ? $memberNfCount : 0,
            'memberJtCount'         => $memberJtCount ? $memberJtCount : 0,
            'nf_name'      => $config->nf_name,
            'jt_name'      => $config->jt_name,


        ];

        return Response()->json(['code'=>200,'msg'=>'获取成功','data'=>$data]);
    }


    public static function getApiList($params= [],$page = 1,$limit = 10,$member)
    {
        $where = [];
        $start=($page-1)*$limit;
        $list = Order::with(['userItem'=>function($query){
            return $query->select(['id','username','name']);
        },'memberItem'=>function($query){
            return $query->select(['id','nickname','avatar']);
        }])->where($where)->where('mid',$member['id'])->orderBy('id','DESC')->skip($start)->take($limit)->get(['id','mid','order_no','room_id','building_no','floor_no','room_no','water_type','num','price','total_price','status','user_id','refund_reason','pay_at','delivery_at','refund_at','created_at'])->toArray();
        $count = Order::where($where)->count();
        $pageCount = ceil($count/$limit);
        $config = Config::where('id', 1)->first(['id', 'site_name', 'logo_src', 'notice', 'nf_price', 'jt_price', 'jt_name', 'nf_name', 'created_at', 'updated_at']);

        foreach ($list as $k => $item){
            $list[$k]['water_type_name'] = $item['water_type'] == 1 ? $config->nf_name : $config->jt_name;
        }

        $data = [
            'list'          => $list,
            'pageCount'     => $pageCount,
        ];

        return Response()->json(['code'=>200,'msg'=>'获取成功','data'=>$data]);
    }

    /**
     * 下单
     * @param array $params
     * @return mixed
     * @throws \Exception
     */
    public static function createOrder($params = [])
    {
        $token = Request()->header('token');
        $memberInfo = Cache::get($token);
        $roomInfo = FloorRoom::where('building_no',intval($params['building_no']))->where('floor_no',intval($params['floor_no']))->where('room_no',trim($params['room_no']))->first(['id','status']);
        if(!$roomInfo){
            throw new \Exception('公寓楼层房间不存在');
        }
        if($roomInfo->status != 1) throw new \Exception('公寓楼层房间不存在');
        $roomId = $roomInfo->id;
        $start_time = date('Y-m-d');
        $isExist = Order::where('room_id',$roomId)->orderBy('id','DESC')->first();
        if($isExist){
            if($isExist->status == 1){
                throw new \Exception('该公寓楼层房间有一个待支付订单，请前去用户中心支付');
            }elseif($isExist->status == 2){
                throw new \Exception('该公寓楼层房间有一个待配送订单，无需下单');
            }elseif($isExist->status == 3 && $isExist->created_at >= $start_time){
                throw new \Exception('该公寓楼层房间今日已下过订单，无需下单');
            }
        }
        $priceArr = Config::where('id',1)->first(['nf_price','jt_price']);
        $price = intval($params['water_type']) == 1 ? $priceArr['nf_price'] : $priceArr['jt_price'];
        if(empty($price)) throw new \Exception('请选择要配送的桶装水的品牌');
        $data = [
            'mid'               => $memberInfo['id'],
            'order_no'          => orderCreate(),
            'room_id'           => $roomId,
            'building_no'       => intval($params['building_no']),
            'floor_no'          => intval($params['floor_no']),
            'room_no'           => trim($params['room_no']),
            'water_type'        => intval($params['water_type']),
            'num'               => intval($params['num']),
            'price'             => $price,
            'total_price'       => intval($params['num']) * $price,
            'status'            => 1,
            'user_id'           => 0,

        ];
        return Order::create($data);
    }
    /**
     * 取消订单
     */
    public static function cancelOrder($id = 0)
    {
        if(!$id){
            return Response()->json(['code'=>201,'msg'=>'参数缺失']);
        }
        $orderInfo = Order::where('id',$id)->first();
        if(!$orderInfo){
            return Response()->json(['code'=>201,'msg'=>'订单不存在']);
        }
        if($orderInfo->status != 1){
            return Response()->json(['code'=>201,'msg'=>'订单不支持取消']);
        }
        $orderInfo->status = 33;
        $save = $orderInfo->save();
        if(!$save){
            return Response()->json(['code'=>201,'msg'=>'操作失败']);
        }
        return Response()->json(['code'=>200,'msg'=>'操作成功']);

    }

}
